﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using Newtonsoft.Json;

namespace working.View
{
    public partial class SettingCmdForm : Form
    {
        public Action<string> onChange { get; set; }

        delegate void AppendValueDelegate(string strValue);
        private const char seperator = '\\';
        private ConfigLogic configLogic { get { return ConfigLogic.Instence; } }
        private string cmdName;
        private CmdAgent agent;
        public SettingCmdForm()
        {
            agent = new CmdAgent();
            InitializeComponent();
            treeView1.NodeMouseClick += OnNodeClick;
        }
        private void OnNodeClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            var nodePath = e.Node.FullPath;
            ShowSelectNode(nodePath);

            if (e.Button== MouseButtons.Right)
            {
                contextMenuStrip1.Show(MousePosition);
            }
        }

        void ReloadView(string cmdName)
        {
            treeView1.Nodes.Clear();
            var root = configLogic.GetCmdItems(cmdName);
            MakeTreeNode(treeView1.Nodes, root.ToArray());
            foreach (TreeNode node in treeView1.Nodes){
                node.ExpandAll();
            }
            treeView1.Update();
        }

        private void MakeTreeNode(TreeNodeCollection nodes, CmdItem[] root)
        {
            nodes.Clear();
            if (root != null)
            {
                for (int i = 0; i < root.Length; i++)
                {
                    var cmdItem = root[i];
                    TreeNode childNode = new TreeNode(cmdItem.name);
                    nodes.Add(childNode);
                    if (cmdItem.haveChild && cmdItem is ParentCmdItem)
                    {
                        MakeTreeNode(childNode.Nodes, (cmdItem as ParentCmdItem).childItems.ToArray());
                    }
                }
            }
        }

        private void button_check_Click(object sender, EventArgs e)
        {
            var cmdText = richTextBox_cmdInfo.Text;
            ThreadPool.QueueUserWorkItem(ThreadStartCheck, cmdText);
            //ThreadStartCheck(cmdText);
        }

        private void ThreadStartCheck(object cmdText)
        {
            try
            {
                agent.RunCmd(cmdText.ToString(),(result) => {
                    richTextBox_output.BeginInvoke(new AppendValueDelegate((x) =>
                    {
                        richTextBox_output.Text += result;
                    }), new object[] { result });
                });
              
            }
            catch (Exception e0)
            {
                MessageBox.Show(e0.Message);
            }
        }

        private void button_record_Click(object sender, EventArgs e)
        {
            var title = textBox_cmdName.Text;
            var cmdInfo = richTextBox_cmdInfo.Text;
            if (title.Contains(seperator))
            {
                var index = title.LastIndexOf(seperator);
                var title0 = title.Substring(index + 1);
                var title1 = title.Substring(0, index);
                RecordToCmd(title0, title1.Split(seperator), cmdInfo);
            }
            else
            {
                RecordToCmd(title, null, cmdInfo);
            }
            ReloadView(cmdName);
        }
        
        private void RecordToCmd(string title, string[] path, string cmdInfo)
        {
            if (path == null || path.Length == 0)
            {
                var oldItem =Array.Find(configLogic.GetCmdItems(cmdName),x => x.name == title);
                if (oldItem == null)
                {
                    CmdItem1 newItem = new CmdItem1();
                    newItem.name = title;
                    newItem.path = "";
                    newItem.text = cmdInfo;
                    configLogic.AddCmdItem(cmdName,newItem);
                }
                else
                {
                    oldItem.text = cmdInfo;
                }
            }
            else
            {
                var path0 = path[0];
                var firstItem = Array.Find(configLogic.GetCmdItems(cmdName),x => x.name == path0);
                if(firstItem == null)
                {
                    firstItem = new CmdItem1();
                    firstItem.path = "";
                    firstItem.name = path0;
                    firstItem.text = "";
                    configLogic.AddCmdItem(cmdName, firstItem as CmdItem1);
                }
                MakeItemDeepth(title, path, 1, firstItem as CmdItem1, cmdInfo);
            }
        }

        private void MakeItemDeepth(string name, string[] paths, int index, ParentCmdItem parent,string cmdInfo)
        {
            if (paths.Length <= index)
            {
                var firstItem = Array.Find(parent.childItems, x => x.name == name);
                if(firstItem == null){
                    firstItem = parent.AddChild();
                    firstItem.name = name;
                }
                firstItem.text = cmdInfo;
                firstItem.path = string.Join(seperator.ToString(), paths);
            }
            else
            {
                var path0 = paths[index];
                var firstItem =Array.Find(parent.childItems,x => x.name == path0);
                if(firstItem == null)
                {
                    firstItem = parent.AddChild();
                    firstItem.path = string.Join(seperator.ToString(), paths, 0, index);
                    firstItem.name = path0;
                    firstItem.text = "";
                }

                if(firstItem is ParentCmdItem)
                {
                    MakeItemDeepth(name, paths, index + 1, firstItem as ParentCmdItem, cmdInfo);
                }
                else
                {
                    MessageBox.Show("!!!层级超过设计的最大值:" + (index + 1));
                }
            }
        }

        private void ShowSelectNode(string path)
        {
            var paths = path.Split(seperator);
            if(paths.Length >0)
            {
                var path0 = paths[0];
                CmdItem rootItem = Array.Find(configLogic.GetCmdItems(cmdName),x => x.name == path0);
                if (rootItem == null) return;

                for (int i = 1; i < paths.Length; i++)
                {
                    var currPath = paths[i];
                    if(rootItem is ParentCmdItem)
                    {
                        var child = Array.Find((rootItem as ParentCmdItem).childItems, x => x.name == currPath);
                        if (child != null)
                        {
                            rootItem = child as ParentCmdItem;
                        }
                        else
                        {
                            break;
                        }
                    }
                   
                }
                textBox_cmdName.Text = path;
                richTextBox_cmdInfo.Text = rootItem.text;
            }
            
        }

        private void button_import_Click(object sender, EventArgs e)
        {
            var filePath = Util.OpenFileSelect("选择导入的json文本", null, "JSON *.json|*.json");
            if(!string.IsNullOrEmpty(filePath))
            {
                var jsonText = System.IO.File.ReadAllText(filePath);
                var cmdList = JsonConvert.DeserializeObject<List<CmdItem1>>(jsonText);
                if(cmdList != null)
                {
                    configLogic.SetCmdItems(cmdName,cmdList);
                    ReloadView(cmdName);
                }
            }
        }

        private void button_export_Click(object sender, EventArgs e)
        {
            var filePath = Util.SaveFileSelect("保存导出的json文本", null, "JSON *.json|*.json");
            if (!string.IsNullOrEmpty(filePath))
            {
                JsonSerializerSettings setting =new JsonSerializerSettings();
                setting.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
                var jsonText = JsonConvert.SerializeObject(configLogic.GetCmdItems(cmdName),Formatting.Indented, setting);
                System.IO.File.WriteAllText(filePath, jsonText);
                Util.OpenFolderAndSelectFile(filePath);
            }
        }

        private void button_clear_Click(object sender, EventArgs e)
        {
            richTextBox_output.Text = "";
        }

        private void delete_ToolStripMenuItem_Click(object sender, EventArgs e)
        {
           var selectedPath = treeView1.SelectedNode.FullPath;
            DeleteNodeFromFullPath(selectedPath);
            ReloadView(cmdName);
        }

        private void DeleteNodeFromFullPath(string path)
        {
            var paths = path.Split(seperator);
            if (paths.Length > 0)
            {
                var path0 = paths[0];
                CmdItem rootItem = Array.Find(configLogic.GetCmdItems(cmdName),x => x.name == path0);
                if (rootItem == null) return;
                if(paths.Length == 1)
                {
                    configLogic.RemoveCmdItem(cmdName,rootItem as CmdItem1);
                }
                else
                {
                    ParentCmdItem parentItem =null;
                    for (int i = 1; i < paths.Length; i++)
                    {
                        var currPath = paths[i];
                        if (rootItem is ParentCmdItem)
                        {
                            var child = Array.Find((rootItem as ParentCmdItem).childItems, x => x.name == currPath);
                            if (child != null)
                            {
                                parentItem = rootItem as ParentCmdItem;
                                rootItem = child as ParentCmdItem;
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                    if(parentItem != null && parentItem != rootItem)
                    {
                        parentItem.RemoveChild(rootItem);
                    }
                }
               
            }

        }

        internal void ShowCmdForm(string cmdName)
        {
            Show();
            this.cmdName = cmdName;
            ReloadView(cmdName);
        }


        protected override void OnClosing(CancelEventArgs e)
        {
            base.OnClosing(e);
            e.Cancel = true;
            configLogic.SaveCmdList();
            if (onChange != null)
                onChange.Invoke(cmdName);
            Hide();
        }

        private void toolStripMenuItem_moveup_Click(object sender, EventArgs e)
        {
            if (treeView1.SelectedNode == null) return;
            var selectedPath = treeView1.SelectedNode.FullPath;
            if (string.IsNullOrEmpty(selectedPath)) return;

            var paths = selectedPath.Split(seperator);
            if (paths.Length > 0)
            {
                var path0 = paths[0];
                CmdItem rootItem = Array.Find(configLogic.GetCmdItems(cmdName), x => x.name == path0);
                if (rootItem == null) return;
                if (paths.Length == 1)
                {
                    configLogic.MoveUpCmdItem(cmdName, rootItem as CmdItem1);
                }
                else
                {
                    ParentCmdItem parentItem = null;
                    for (int i = 1; i < paths.Length; i++)
                    {
                        var currPath = paths[i];
                        if (rootItem is ParentCmdItem)
                        {
                            var child = Array.Find((rootItem as ParentCmdItem).childItems, x => x.name == currPath);
                            if (child != null)
                            {
                                parentItem = rootItem as ParentCmdItem;
                                rootItem = child as ParentCmdItem;
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                    if (parentItem != null && parentItem != rootItem)
                    {
                        parentItem.MoveUpCmdItem(rootItem);
                    }
                }

            }

            ReloadView(cmdName);
        }

        private void toolStripMenuItem_movedown_Click(object sender, EventArgs e)
        {
            if (treeView1.SelectedNode == null) return;

            var selectedPath = treeView1.SelectedNode.FullPath;
            if (string.IsNullOrEmpty(selectedPath)) return;
            var paths = selectedPath.Split(seperator);
            if (paths.Length > 0)
            {
                var path0 = paths[0];
                CmdItem rootItem = Array.Find(configLogic.GetCmdItems(cmdName), x => x.name == path0);
                if (rootItem == null) return;
                if (paths.Length == 1)
                {
                    configLogic.MoveDownCmdItem(cmdName, rootItem as CmdItem1);
                }
                else
                {
                    ParentCmdItem parentItem = null;
                    for (int i = 1; i < paths.Length; i++)
                    {
                        var currPath = paths[i];
                        if (rootItem is ParentCmdItem)
                        {
                            var child = Array.Find((rootItem as ParentCmdItem).childItems, x => x.name == currPath);
                            if (child != null)
                            {
                                parentItem = rootItem as ParentCmdItem;
                                rootItem = child as ParentCmdItem;
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                    if (parentItem != null && parentItem != rootItem)
                    {
                        parentItem.MoveDownCmdItem(rootItem);
                    }
                }

            }

            ReloadView(cmdName);
        }
    }
}
